package org.jim.server.helper.db;

import java.util.*;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.jim.common.listener.ImBindListener;
import org.jim.common.message.IMesssageHelper;
import org.jim.common.packets.ChatBody;
import org.jim.common.packets.Group;
import org.jim.common.packets.User;
import org.jim.common.packets.UserMessageData;
import org.jim.common.utils.ChatKit;
import org.jim.common.utils.JsonKit;
import org.jim.server.ImServerGroupContext;
import org.jim.server.helper.db.mybatis.MyBatisUtil;
import org.jim.server.helper.db.mybatis.dao.GroupMessageMapper;
import org.jim.server.helper.db.mybatis.dao.UserMessageMapper;
import org.jim.server.helper.db.mybatis.model.GroupMessage;
import org.jim.server.helper.db.mybatis.model.UserMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Mysql获取持久化+同步消息助手;
 * @author WChao
 * @date 2018年4月10日 下午4:06:26
 */
public class MysqlMessageHelper implements IMesssageHelper {
	private Logger log = LoggerFactory.getLogger(ImServerGroupContext.class);

	static SqlSessionFactory sqlSessionFactory = null;
	static {
		sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
	}

	@Override
	public ImBindListener getBindListener() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void addGroupUser(String userid, String group_id) {
		// TODO Auto-generated method stub

	}

	@Override
	public List<String> getGroupUsers(String group_id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void writeMessage(String timelineTable, String timelineId, ChatBody chatBody) {
		// TODO Auto-generated method stub
		Integer chatType = chatBody.getChatType();
		//1：群聊，2：私聊
		if(1 == chatType ){
			GroupMessageAdd(chatBody);
		}else if(2 == chatType ){
			if(null == getUserMessageByRedisId(chatBody.getId()) || getUserMessageByRedisId(chatBody.getId()).size()==0) {
				UserMessageAdd(chatBody);
			}
		}else{
			log.error("Mysql获取持久化时chatType异常,请检查！",chatBody);
		}

	}

	@Override
	public void removeGroupUser(String userid, String group_id) {
		// TODO Auto-generated method stub

	}

	@Override
	public UserMessageData getFriendsOfflineMessage(String userid, String from_userid) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public UserMessageData getFriendsOfflineMessage(String userid) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public UserMessageData getGroupOfflineMessage(String userid, String groupid) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public UserMessageData getFriendHistoryMessage(String userid, String from_userid,Double beginTime,Double endTime,Integer offset,Integer count) {
		List<ChatBody> messages = null;
		boolean isTimeBetween = (beginTime != null && endTime != null);
		boolean isPage = (offset != null && count != null);
		Map map = new HashMap();
		map.put("from",userid);
		map.put("to",from_userid);
		map.put("beginTime",beginTime);
		map.put("endTime",endTime);
		if(isTimeBetween && !isPage){//消息区间，不分页

		}else if(isTimeBetween && isPage){//消息区间，并且分页;

		}else if(!isTimeBetween &&  isPage){//所有消息，并且分页;
			offset = count*(offset-1);
			map.put("offset",offset);
			map.put("count",count);
			List<UserMessage> userMessage = getUserMessage(map);
			Collections.reverse(userMessage);
			messages = userMessageToString(userMessage);
		}else{//所有消息，不分页;
			List<UserMessage> userMessage = getUserMessage(map);
			messages = userMessageToString(userMessage);
		}
		if(messages == null || messages.size() == 0) {
			return null;
		}
		UserMessageData messageData = new UserMessageData(userid);
		putFriendsHistoryMessage(messageData, messages,from_userid);
		return messageData;
	}

	@Override
	public UserMessageData getGroupHistoryMessage(String userid, String groupid,Double beginTime,Double endTime,Integer offset,Integer count) {
		List<String> messages = null;
		boolean isTimeBetween = (beginTime != null && endTime != null);
		boolean isPage = (offset != null && count != null);
		Map map = new HashMap();
		map.put("from",userid);
		map.put("groupId",groupid);
		map.put("beginTime",beginTime);
		map.put("endTime",endTime);
		if(isTimeBetween && !isPage){//消息区间，不分页

		}else if(isTimeBetween && isPage){//消息区间，并且分页;

		}else if(!isTimeBetween &&  isPage){//所有消息，并且分页;

		}else{//所有消息，不分页;
			List<GroupMessage> groupMessage = getGroupMessage(map);
			messages = groupMessageToString(groupMessage);
		}
		if(messages == null || messages.size() == 0) {
			return null;
		}
		UserMessageData messageData = new UserMessageData(userid);
		putGroupMessage(messageData, JsonKit.toArray(messages, ChatBody.class));
		return messageData;
	}

	@Override
	public boolean isOnline(String userid) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Group getGroupUsers(String group_id, Integer type) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Group> getAllGroupUsers(String user_id, Integer type) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Group getFriendUsers(String user_id, String friend_group_id, Integer type) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Group> getAllFriendUsers(String user_id, Integer type) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public User getUserByType(String userid, Integer type) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<String> getGroups(String user_id) {
		// TODO Auto-generated method stub
		return null;
	}

	private static void GroupMessageAdd(ChatBody chatBody) {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			GroupMessageMapper groupMessageMapper = sqlSession.getMapper(GroupMessageMapper.class);
			String extras = null;
			if(chatBody.getExtras() != null){
				extras = chatBody.getExtras().toJSONString();
			}
			GroupMessage groupMessage = new GroupMessage(chatBody.getId(),chatBody.getChatType(),chatBody.getCmd(),chatBody.getContent(),chatBody.getCreateTime(),chatBody.getFrom(),chatBody.getGroup_id(),chatBody.getMsgType(),chatBody.getVisit_no(),extras);
			groupMessageMapper.insertGroupMessage(groupMessage);
			sqlSession.commit();// 这里一定要提交，不然数据进不去数据库中
		} finally {
			sqlSession.close();
		}
	}

	private static void UserMessageAdd(ChatBody chatBody) {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			UserMessageMapper userMessageMapper = sqlSession.getMapper(UserMessageMapper.class);
			String extras = null;
			if(chatBody.getExtras() != null){
				extras = chatBody.getExtras().toJSONString();
			}
			UserMessage userMessage = new UserMessage(chatBody.getId(),chatBody.getChatType(),chatBody.getCmd(),chatBody.getContent(),chatBody.getCreateTime(),chatBody.getFrom(),chatBody.getTo(),chatBody.getMsgType(), chatBody.getVisit_no(), extras);
			userMessageMapper.insertUserMessage(userMessage);
			sqlSession.commit();// 这里一定要提交，不然数据进不去数据库中
		} finally {
			sqlSession.close();
		}
	}

	/**
	 * 放入用户好友历史消息;
	 */
	public UserMessageData putFriendsHistoryMessage(UserMessageData userMessage , List<ChatBody> messages,String friendId){
		if(userMessage == null || messages == null)
			return null;
		for(ChatBody chatBody : messages){
			String fromUserId = chatBody.getFrom();
			if(StringUtils.isEmpty(fromUserId)) {
				continue;
			}
			List<ChatBody> friendMessages = userMessage.getFriends().get(friendId);
			if(friendMessages == null){
				friendMessages = new ArrayList<ChatBody>();
				userMessage.getFriends().put(friendId, friendMessages);
			}
			friendMessages.add(chatBody);
		}
		return userMessage;
	}
	/**
	 * 放入用户群组消息;
	 */
	public UserMessageData putGroupMessage(UserMessageData userMessage,List<ChatBody> messages){
		if(userMessage == null || messages == null)
			return null;
		for(ChatBody chatBody : messages){
			String group = chatBody.getGroup_id();
			if(StringUtils.isEmpty(group)) {
				continue;
			}
			List<ChatBody> groupMessages = userMessage.getGroups().get(group);
			if(groupMessages == null){
				groupMessages = new ArrayList<ChatBody>();
				userMessage.getGroups().put(group, groupMessages);
			}
			groupMessages.add(chatBody);
		}
		return userMessage;
	}
	/**
	 * mysql获取好友私聊数据;
	 * @param map
	 */
	private List<UserMessage> getUserMessage(Map map) {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			UserMessageMapper userMessageMapper = sqlSession.getMapper(UserMessageMapper.class);
			List<UserMessage> userMessage = userMessageMapper.getUserMessage(map);
			return userMessage;
		} finally {
			sqlSession.close();
		}
	}

	/**
	 * mysql获取好友私聊数据;
	 * @param redisId
	 */
	private List<UserMessage> getUserMessageByRedisId(String redisId) {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			UserMessageMapper userMessageMapper = sqlSession.getMapper(UserMessageMapper.class);
			List<UserMessage> userMessage = userMessageMapper.getUserMessageByRedisId(redisId);
			return userMessage;
		} finally {
			sqlSession.close();
		}
	}
	/**
	 * mysql获取好友私聊数据;
	 * @param map
	 */
	private List<GroupMessage> getGroupMessage(Map map) {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			GroupMessageMapper groupMessageMapper = sqlSession.getMapper(GroupMessageMapper.class);
			List<GroupMessage> groupMessage = groupMessageMapper.getGroupMessage(map);
			return groupMessage;
		} finally {
			sqlSession.close();
		}
	}
	/**
	 * 转换为json格式;
	 * @param userMessageList
	 */
	private List<ChatBody> userMessageToString(List<UserMessage> userMessageList) {
		List<ChatBody> list = new ArrayList<>();
		for(UserMessage userMessage: userMessageList){
			ChatBody chatBody = new ChatBody.Builder().build();
			BeanUtil.copyProperties(userMessage,chatBody);
			chatBody.setExtras(JSONObject.parseObject(userMessage.getExtras()));
			list.add(chatBody);
		}
		return list;
	}
	/**
	 * 转换为json格式;
	 * @param groupMessageList
	 */
	private List<String> groupMessageToString(List<GroupMessage> groupMessageList) {
		List<String> list = new ArrayList<>();
		for(GroupMessage groupMessage: groupMessageList){
			list.add(groupMessage.toString());
		}
		return list;
	}
}
